package es.aqua.aquac.il.domain;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.PostLoad;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

import org.springframework.binding.message.MessageBuilder;
import org.springframework.binding.message.MessageContext;
import org.springframework.binding.validation.ValidationContext;

import es.aqua.aquac.util.Constants;
import es.aqua.aquac.util.KeysProperties;
import es.aqua.aquac.util.Utiles;

@Entity
@Table(name = "FACTURAS")
public class Factura extends BaseDomainObject implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 5726854315603495717L;

	/**
	 * Id
	 */
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "FACTURA_ID")
	private Integer id;

	/**
	 * Numero
	 */
	@Column(name = "NUMERO", nullable = false, length = Constants.DB_TAM_TEXTO_MEDIANO)
	private String numero = "";

	/**
	 * Desde
	 */
	@Column(name = "FECHA_DESDE", nullable = false)
	@Temporal(TemporalType.DATE)
	private Date fechaDesde;

	/**
	 * Hasta
	 */
	@Column(name = "FECHA_HASTA", nullable = false)
	@Temporal(TemporalType.DATE)
	private Date fechaHasta;

	/**
	 * Importe Residuos Solidos Urbanos
	 */
	@Column(name = "IMPORTE_RSU", nullable = false, precision = Constants.DB_TAM_PRECISION)
	private Double importeRSU;

	/**
	 * Importe Ciclo del Agua
	 */
	@Column(name = "IMPORTE_CUOTA", nullable = false, precision = Constants.DB_TAM_PRECISION)
	private Double importeCuota;

	/**
	 * Importe Ciclo del Agua
	 */
	@Column(name = "IMPORTE_AGUA", nullable = false, precision = Constants.DB_TAM_PRECISION)
	private Double importeAgua;

	/**
	 * Importe Total
	 */
	@Transient
	private Double total;

	/**
	 * Importe m3
	 */
	@Transient
	private Double importem3;

	/**
	 * Importe importeCuotaPropietario
	 */
	@Transient
	private Double importeCuotaPropietario;

	/**
	 * Importe importeRSUPropietario
	 */
	@Transient
	private Double importeRSUPropietario;

	/**
	 * Lecturas
	 */
	@Column(name = "LECTURAS", nullable = false, precision = Constants.DB_TAM_PRECISION)
	private Double lecturas;

	/**
	 * Consumo
	 */
	@Column(name = "CONSUMO", nullable = false, precision = Constants.DB_TAM_PRECISION)
	private Double consumo;

	/**
	 * Lista de recibos de una factura.
	 */
	@Transient
	private List<Recibo> lstRecibos = new ArrayList<Recibo>();

	/**
	 * Sumatorio de consumo
	 */
	@Transient
	private Double consumoSumatorio;

	/**
	 * Sumatorio de total
	 */
	@Transient
	private Double totalSumatorio;

	/**
	 * Indica si el cosumo y el total cuadra
	 */
	@Transient
	private Boolean bCuadraRecibo;

	/**
	 * Indica si ya se han generado los recibos
	 */
	@Transient
	private Boolean bRecibosGuardados;

	/**
	 * @return the id
	 */
	public Integer getId() {
		return id;
	}

	/**
	 * @param id
	 *            the id to set
	 */
	public void setId(Integer id) {
		this.id = id;
	}

	/**
	 * @return the numero
	 */
	public String getNumero() {
		return numero;
	}

	/**
	 * @return the consumoSumatorio
	 */
	public Double getConsumoSumatorio() {
		return consumoSumatorio;
	}

	/**
	 * @param consumoSumatorio
	 *            the consumoSumatorio to set
	 */
	public void setConsumoSumatorio(Double consumoSumatorio) {
		this.consumoSumatorio = consumoSumatorio;
	}

	/**
	 * @return the bCuadraRecibo
	 */
	public Boolean getbCuadraRecibo() {
		return bCuadraRecibo;
	}

	/**
	 * @param bCuadraRecibo
	 *            the bCuadraRecibo to set
	 */
	public void setbCuadraRecibo(Boolean bCuadraRecibo) {
		this.bCuadraRecibo = bCuadraRecibo;
	}

	/**
	 * @return the totalSumatorio
	 */
	public Double getTotalSumatorio() {
		return totalSumatorio;
	}

	/**
	 * @param totalSumatorio
	 *            the totalSumatorio to set
	 */
	public void setTotalSumatorio(Double totalSumatorio) {
		this.totalSumatorio = totalSumatorio;
	}

	/**
	 * @param numero
	 *            the numero to set
	 */
	public void setNumero(String numero) {
		this.numero = numero;
	}

	/**
	 * @return the fechaDesde
	 */
	public Date getFechaDesde() {
		return fechaDesde;
	}

	/**
	 * @param fechaDesde
	 *            the fechaDesde to set
	 */
	public void setFechaDesde(Date fechaDesde) {
		this.fechaDesde = fechaDesde;
	}

	/**
	 * @return the fechaHasta
	 */
	public Date getFechaHasta() {
		return fechaHasta;
	}

	/**
	 * @param fechaHasta
	 *            the fechaHasta to set
	 */
	public void setFechaHasta(Date fechaHasta) {
		this.fechaHasta = fechaHasta;
	}

	/**
	 * @return the importeRSU
	 */
	public Double getImporteRSU() {
		return importeRSU;
	}

	/**
	 * @param importeRSU
	 *            the importeRSU to set
	 */
	public void setImporteRSU(Double importeRSU) {
		this.importeRSU = importeRSU;
	}

	/**
	 * @return the importeAgua
	 */
	public Double getImporteAgua() {
		return importeAgua;
	}

	/**
	 * @param importeAgua
	 *            the importeAgua to set
	 */
	public void setImporteAgua(Double importeAgua) {
		this.importeAgua = importeAgua;
	}

	/**
	 * @return the consumo
	 */
	public Double getConsumo() {
		return consumo;
	}

	/**
	 * @param consumo
	 *            the consumo to set
	 */
	public void setConsumo(Double consumo) {
		this.consumo = consumo;
	}

	/**
	 * @return the lecturas
	 */
	public Double getLecturas() {
		return lecturas;
	}

	/**
	 * @param lecturas
	 *            the lecturas to set
	 */
	public void setLecturas(Double lecturas) {
		this.lecturas = lecturas;
	}

	/**
	 * @return the importeCuota
	 */
	public Double getImporteCuota() {
		return importeCuota;
	}

	/**
	 * @param importeCuota
	 *            the importeCuota to set
	 */
	public void setImporteCuota(Double importeCuota) {
		this.importeCuota = importeCuota;
	}

	/**
	 * @return the total
	 */
	public Double getTotal() {
		return total;
	}

	/**
	 * @param total
	 *            the total to set
	 */
	public void setTotal(Double total) {
		this.total = total;
	}

	/**
	 * @return the importem3
	 */
	public Double getImportem3() {
		return importem3;
	}

	/**
	 * @param importem3
	 *            the importem3 to set
	 */
	public void setImportem3(Double importem3) {
		this.importem3 = importem3;
	}

	/**
	 * @return the importeCuotaPropietario
	 */
	public Double getImporteCuotaPropietario() {
		return importeCuotaPropietario;
	}

	/**
	 * @param importeCuotaPropietario
	 *            the importeCuotaPropietario to set
	 */
	public void setImporteCuotaPropietario(Double importeCuotaPropietario) {
		this.importeCuotaPropietario = importeCuotaPropietario;
	}

	/**
	 * @return the importeRSUPropietario
	 */
	public Double getImporteRSUPropietario() {
		return importeRSUPropietario;
	}

	/**
	 * @param importeRSUPropietario
	 *            the importeRSUPropietario to set
	 */
	public void setImporteRSUPropietario(Double importeRSUPropietario) {
		this.importeRSUPropietario = importeRSUPropietario;
	}

	/**
	 * @return the lstRecibos
	 */
	public List<Recibo> getLstRecibos() {
		return lstRecibos;
	}

	/**
	 * @param lstRecibos
	 *            the lstRecibos to set
	 */
	public void setLstRecibos(List<Recibo> lstRecibos) {
		this.lstRecibos = lstRecibos;
	}

	public Boolean getbRecibosGuardados() {
		return bRecibosGuardados;
	}

	public void setbRecibosGuardados(Boolean bRecibosGuardados) {
		this.bRecibosGuardados = bRecibosGuardados;
	}

	/**
	 * Validaciones
	 * 
	 * @param context
	 */
	public void validateDatosFactura(ValidationContext context) {

		MessageContext messages = context.getMessageContext();

		if (this.getFechaDesde() == null) {
			messages.addMessage(new MessageBuilder().error().defaultText(Utiles.textoResource(KeysProperties.MENSAJE_DATO_OBLIGATORIO)).build());
		}
		if (this.getFechaHasta() == null) {
			messages.addMessage(new MessageBuilder().error().defaultText(Utiles.textoResource(KeysProperties.MENSAJE_DATO_OBLIGATORIO)).build());
		}
		if (this.getNumero() == null || (this.getNumero() != null && !Utiles.validarString(this.getNumero()))) {
			messages.addMessage(new MessageBuilder().error().defaultText(Utiles.textoResource(KeysProperties.MENSAJE_DATO_OBLIGATORIO)).build());
		}
		if (this.getLecturas() == null) {
			messages.addMessage(new MessageBuilder().error().defaultText(Utiles.textoResource(KeysProperties.MENSAJE_DATO_OBLIGATORIO)).build());
		}
		if (this.getConsumo() == null) {
			messages.addMessage(new MessageBuilder().error().defaultText(Utiles.textoResource(KeysProperties.MENSAJE_DATO_OBLIGATORIO)).build());
		}

	}

	@PostLoad
	public void total() {

		this.total = this.importeAgua + this.importeCuota + this.importeRSU;

		this.importem3 = this.importeAgua / this.consumo;

		this.importeCuotaPropietario = this.importeCuota / Constants.NUMERO_PROPIETARIOS;

		this.importeRSUPropietario = this.importeRSU / Constants.NUMERO_PROPIETARIOS;
	}
}
